package com.se.db;

import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
import com.se.exception.DbLoadingException;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Properties;

/**
 * 数据库连接工具类，使用Hikari连接池管理数据库连接
 */
public class DbUtils {
    private static String URL;
    private static String User;
    private static String Pwd;
    private static final Properties properties = new Properties();
    private static final HikariDataSource dataSource;
    private static final Logger logger = LoggerFactory.getLogger(DbUtils.class);

    public static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);

    /*
      * 静态代码块，在编译时初始化
     */
    static {
        try (InputStream input = DbUtils.class.getResourceAsStream("/db-config.properties")) {
            properties.load(input);
            URL = properties.getProperty("jdbc.url");
            User = properties.getProperty("jdbc.username");
            Pwd = properties.getProperty("jdbc.password");
            HikariConfig config = new HikariConfig();
            config.setJdbcUrl(URL);
            config.setUsername(User);
            config.setPassword(Pwd);
            config.setMaxLifetime(500);
            config.setLeakDetectionThreshold(2000);
            config.setMaximumPoolSize(20);
            dataSource = new HikariDataSource(config);
            logger.info("============数据库初始化完成============");
        } catch (IOException e) {
            throw new DbLoadingException("加载数据库配置失败", e);
        }
    }

    // 私有构造函数防止实例化
    private DbUtils(){
    }

    public static void init(){
        logger.info("============数据库初始化开始============");
    }

    /**
     * 获取数据库连接（从连接池获取）
     * @return Connection对象（需自行关闭）
     */
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            logger.error("获取数据库连接失败: {}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 关闭数据库连接池（应在应用关闭时调用）
     */
    public static void shutDown(){
        if(dataSource !=null){
            dataSource.close();
            AbandonedConnectionCleanupThread.uncheckedShutdown(); //没什么屌用，防止maven警告
        }
    }

    /**
     * 通用资源关闭方法（支持可变参数）
     * @param res 需要关闭的资源列表（AutoCloseable接口实现）
     */
    public static void close(AutoCloseable...res){
        for(var re : res){
            if(re != null){
                try {
                    re.close();
                } catch (Exception e) {
                    logger.warn("资源释放异常: {}", e.getMessage(), e);
                }
            }
        }
    }
}
